package com.yz.jdd.module.upgrade;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;

import androidx.core.app.NotificationCompat;
import androidx.core.content.FileProvider;

import com.tonyodev.fetch2.AbstractFetchListener;
import com.tonyodev.fetch2.Download;
import com.tonyodev.fetch2.Error;
import com.tonyodev.fetch2.Fetch;
import com.tonyodev.fetch2.FetchConfiguration;
import com.tonyodev.fetch2.FetchListener;
import com.tonyodev.fetch2.NetworkType;
import com.tonyodev.fetch2.Priority;
import com.tonyodev.fetch2.Request;
import com.tonyodev.fetch2okhttp.OkHttpDownloader;
import com.yz.jdd.R;
import com.yz.jdd.base.MyApplication;
import com.yz.jdd.base.event.Events;
import com.yz.jdd.base.event.RxBus;
import com.yz.jdd.base.utils.LogUtils;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Response;

/**
 * 版本更新提示 , apk下载调用安装 ;
 * 190904 jmliu
 */
public class NewAPKDownLoaderService extends Service {

    private Context mContext;
    private String url;
    private Fetch fetch;
    String tempPath;
    //发送广播
//    Intent intent;

    //初始化通知
    NotificationManager notificationManager;
    NotificationCompat.Builder builder;
    Notification notification;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        //初始 fetch
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .build();
        FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
                .setDownloadConcurrentLimit(3)
                .setHttpDownloader(new OkHttpDownloader(okHttpClient))
                .build();
        fetch = Fetch.Impl.getInstance(fetchConfiguration);
        fetch.addListener(fetchListener);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            url = intent.getStringExtra("url");
            fetch.deleteAll();
            String downloadPath;
            List<Request> requests = new ArrayList<>();
            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                downloadPath = Environment.getExternalStorageDirectory()
                        .getPath();
            } else {
                downloadPath = mContext.getFilesDir().getAbsolutePath();
            }
            File file = new File(downloadPath);
            if (file.exists()) {
                file.delete();
            }
            file.mkdir();
            tempPath = downloadPath + File.separator + "temp.apk";
            Request request = new Request(url, tempPath);
            request.setPriority(Priority.HIGH);
            request.setNetworkType(NetworkType.ALL);
            requests.add(request);
//            fetch.enqueue(requests, new Func<List<Pair<Request, Error>>>() {
//                @Override
//                public void call(@NotNull List<Pair<Request, Error>> pairs) {
//                    LogUtils.i("pairs----- " + pairs);
//                }
//            });
            initNotification();
            downLoadFile(url, tempPath);
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private void initNotification() {
        notificationManager = (NotificationManager) MyApplication.application.getSystemService(Context.NOTIFICATION_SERVICE);
        builder = new NotificationCompat.Builder(MyApplication.application, createNotificationChannel(MyApplication.application));
        builder.setContentTitle("正在更新...") //设置通知标题
                .setSmallIcon(R.mipmap.icon)
                .setLargeIcon(BitmapFactory.decodeResource(MyApplication.application.getResources(), R.mipmap.icon)) //设置通知的大图标
                .setDefaults(Notification.DEFAULT_LIGHTS) //设置通知的提醒方式： 呼吸灯
                .setPriority(NotificationCompat.PRIORITY_MAX) //设置通知的优先级：最大
                .setAutoCancel(false)//设置通知被点击一次是否自动取消
                .setContentText("下载进度:" + "0%")
                .setProgress(100, 0, false);
        notification = builder.build();//构建通知对象

    }

    private FetchListener fetchListener = new AbstractFetchListener() {
        @Override
        public void onProgress(@NotNull Download download, long etaInMilliSeconds, long downloadedBytesPerSecond) {
            super.onProgress(download, etaInMilliSeconds, downloadedBytesPerSecond);
            LogUtils.i("主页面 Progress: " + download.getProgress());
            builder.setProgress(100, download.getProgress(), false);
            builder.setContentText("下载进度:" + download.getProgress() + "%");
            notification = builder.build();
            notificationManager.notify(1, notification);

            RxBus.getInstance().send(Events.EVENT_DOWNLOAD_PROGRESS, download.getProgress());
        }

        @Override
        public void onError(Download download, Error error, Throwable throwable) {
            super.onError(download, error, throwable);
            onDownloadError("Error: " + download.getError().toString());
        }

        @Override
        public void onCompleted(@NotNull Download download) {
            super.onCompleted(download);
            onDownloadCompleted(download.getFile());
        }
    };

    public static String createNotificationChannel(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String channelId = "channelId";
            CharSequence channelName = "channelName";
            String channelDescription = "channelDescription";
            // int channelImportance = NotificationManager.IMPORTANCE_DEFAULT; // 有声音提示
            int channelImportance = NotificationManager.IMPORTANCE_LOW;

            NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, channelImportance);
            // 设置描述 最长30字符
            notificationChannel.setDescription(channelDescription);
            // 该渠道的通知是否使用震动
            notificationChannel.enableVibration(false);
            // 设置显示模式
            notificationChannel.setLockscreenVisibility(NotificationCompat.VISIBILITY_PUBLIC);

            NotificationManager notificationManager =
                    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(notificationChannel);

            return channelId;
        } else {
            return null;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    /**
     * 带进度文件下载
     *
     * @param fileUrl     文件url
     * @param destFileDir 存储目标目录
     */
    public void downLoadFile(String fileUrl, final String destFileDir) {
        final File file = new File(destFileDir);
        final okhttp3.Request request = new okhttp3.Request.Builder().url(fileUrl).build();
        OkHttpClient okHttpClient = new OkHttpClient().newBuilder().build();
        final Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                onDownloadError("Error: " + e);
            }

            @Override
            public void onResponse(Call call, Response response) {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    long total = response.body().contentLength();
                    Log.e("DownLoaderService", "total------>" + total);
                    long current = 0;
                    is = response.body().byteStream();
                    fos = new FileOutputStream(file);
                    while ((len = is.read(buf)) != -1) {
                        current += len;
                        fos.write(buf, 0, len);
//                        Log.e(TAG, "current------>" + current);
                        long finalCurrent = current;
                        int progress = (int) (100 * finalCurrent / total);
                        LogUtils.i("主页面 Progress: " + progress);
                        builder.setProgress(100, progress, false);
                        builder.setContentText("下载进度:" + progress + "%");
                        notification = builder.build();
                        notificationManager.notify(1, notification);

                        RxBus.getInstance().send(Events.EVENT_DOWNLOAD_PROGRESS, progress);
                    }
                    fos.flush();
                    onDownloadCompleted(file.getAbsolutePath());
                } catch (IOException e) {
                    onDownloadError("Error: " + e);
                } finally {
                    try {
                        if (is != null) {
                            is.close();
                        }
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {
                        Log.e("DownLoaderService", e.toString());
                    }
                }
            }
        });
    }

    private void onDownloadError(final String download) {
        LogUtils.i(download);
        RxBus.getInstance().send(Events.EVENT_DOWNLOAD_PROGRESS, 1001);
        builder.setContentTitle("下载失败")
                .setContentText("请重试...")
                .setAutoCancel(true);//设置通知被点击一次是否自动取消
        notification = builder.build();
        notificationManager.notify(1, notification);
    }

    private void onDownloadCompleted(String apkFile) {
        RxBus.getInstance().send(Events.EVENT_DOWNLOAD_PROGRESS, 1002);
        LogUtils.i("Completed filePath --- onCompleted " + apkFile);
        if (fetch != null && !fetch.isClosed()) {
            fetch.removeListener(fetchListener);
            fetch.close();
        }
        File file = new File(tempPath);
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        String type = "application/vnd.android.package-archive";
        intent.setDataAndType(Uri.fromFile(file), type);
//				mContext.startActivity(intent);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri contentUri = FileProvider.getUriForFile(mContext, "com.yz.jdd.provider", file);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }
        mContext.startActivity(intent);


        builder.setContentTitle("下载完成")
                .setContentText("点击安装")
                .setAutoCancel(true);//设置通知被点击一次是否自动取消

        //点击安装代码块
        Intent intentNotification = new Intent(Intent.ACTION_VIEW);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri contentUri = FileProvider.getUriForFile(mContext, "com.yz.jdd.provider", file);
            intentNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intentNotification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            intentNotification.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intentNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intentNotification.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }
        PendingIntent pi = PendingIntent.getActivity(NewAPKDownLoaderService.this, 0, intentNotification, 0);
        notification = builder.setContentIntent(pi).build();
        notificationManager.notify(1, notification);

        stopSelf();
    }
}
